/***************************************************************************
 *   Copyright (C) 2008 by Justin L. Boss                                  *
 *   justin@rtechguys.com                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "wavemap.h"

WaveMap::WaveMap (int width, int depth, float texture_x, float texture_y, float size, float damping, float update_speed)
{
    startTimer(update_speed);
    WaveSize = size;
    Damp = damping;
    WaveX = width+1;
    WaveY = depth+1;
    OffsetX = 1.0 / texture_x;
    OffsetY = 1.0 / texture_y;
    WaveZ = new float*[WaveX];
    NewWaveZ = new float*[WaveX];
    for (int i=0; i < WaveX; i++ )
    {
        WaveZ[i] = new float[WaveY];
        for (int x = 0; x < WaveY; x++)
            WaveZ[i][x]=0;
        NewWaveZ[i] = new float[WaveY];
        for (int x = 0; x < WaveY; x++)
            NewWaveZ[i][x]=0;
    }
}


WaveMap::~WaveMap()
{
    for (int i=0; i<WaveX; i++ )
    {
        delete [] WaveZ [i];
        delete [] NewWaveZ [i];
    }
    delete [] WaveZ;
    delete [] NewWaveZ;
}


float WaveMap::GetOffset ()
{
    return OffsetY;
}


void WaveMap::UpdateWave ()
{
    float z;
    for (int y=1; y<WaveY-1; y++ )
        for (int x=1; x<WaveX-1; x++ )
        {
            z = ( WaveZ[x-1][y] + WaveZ[x+1][y] + WaveZ[x][y-1] + WaveZ[x][y+1] ) / 2 - NewWaveZ[x][y];
            if ( Damp )
                z = z - ( z / Damp );
            NewWaveZ[x][y] = z;
        }
    float **temp = WaveZ;
    WaveZ = NewWaveZ;
    NewWaveZ = temp;
}


void WaveMap::UpdateWave (int seed )
{
    float z;
    for (int count=0; count<seed; count++ )
    {
        for (int y=1; y<WaveY-1; y++ )
            for (int x=1; x<WaveX-1; x++ )
            {
                z = ( WaveZ[x-1][y] + WaveZ[x+1][y] + WaveZ[x][y-1] + WaveZ[x][y+1] ) / 2 - NewWaveZ[x][y];
                if ( Damp )
                    z = z - ( z / Damp );
                NewWaveZ[x][y] = z;
            }
        float **temp = WaveZ;
        WaveZ = NewWaveZ;
        NewWaveZ = temp;
    }
}


void WaveMap::DisturbWave (int x,int y,int sx,int sy, float mag)
{
    x=x-sx/2;
    y=y-sy/2;
    for (int a = 0; a < sx; a++ )
        for (int i = 0; i < sy ; i++ )
            WaveZ[i+x][a+y]= mag;
}


void WaveMap::SetWaveDamp ( float d )
{
    Damp = 1000 %int ( d );
}


void WaveMap::Render()
{
    glScalef (WaveSize, WaveSize, WaveSize);
    glTranslatef (-WaveX/2, 0.0, -WaveY);
    float ty=0.0;
    float tx=0.0;
    glBegin(GL_QUADS);
    for (int y = 0; y < WaveY-1; y++ )
    {
        ty+=OffsetY;
        for (int x = 0; x < WaveX-1; x++ )
        {
            tx+=OffsetX;
            glTexCoord2f ( tx, ty );
            glVertex3f ( x, WaveZ [x][y], y );
            glTexCoord2f ( tx, ty+OffsetY );
            glVertex3f ( x, WaveZ [x][y+1], y+1 );
            glTexCoord2f ( tx+OffsetX, ty+OffsetY );
            glVertex3f ( x+1, WaveZ[x+1][y+1], y+1 );
            glTexCoord2f ( tx+OffsetX, ty );
            glVertex3f ( x+1, WaveZ[x+1][y], y );
        }
    }
    glEnd( );
}

